package red.stu.mc.mod.codeblock.block;

import javax.script.ScriptEngine;
import javax.script.ScriptException;

import org.apache.commons.codec.binary.Base64;

import net.minecraft.block.Block;
import net.minecraft.block.BlockContainer;
import net.minecraft.block.SoundType;
import net.minecraft.block.material.MapColor;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumBlockRenderType;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.TextComponentString;
import net.minecraft.world.World;
import red.stu.mc.api.Code;
import red.stu.mc.mod.codeblock.CodeBlockMod;
import red.stu.mc.mod.codeblock.client.gui.GuiContainerCodeBlock;
import red.stu.mc.mod.codeblock.inventory.GuiElementLoader;
import red.stu.mc.mod.codeblock.item.ItemLoader;
import red.stu.mc.mod.codeblock.tileentity.TileEntityCodeBlock;
import red.stu.mc.mod.codeblock.util.CodeBlockScriptEngineManager;
import red.stu.mc.mod.codeblock.util.CodeStringTool;
import red.stu.mc.mod.codeblock.util.LanguageTool;

public class BlockCodeBlock extends BlockContainer {
	
	// 脚本引擎工厂
	private static CodeBlockScriptEngineManager scriptEngineManager = new CodeBlockScriptEngineManager();

	public BlockCodeBlock() {
		super(Material.IRON, MapColor.BLUE);
		super.setUnlocalizedName("code_block");
		super.setHardness(0.6f); // 徒手硬度：泥土是0.5,石头是1.5,大部分矿石是3.0
		super.setResistance(50.0f); // 爆炸的抗性,石头是10.0
		super.setLightLevel(0f); // 发光亮度,范围是0.0~1.0,南瓜灯,萤石和岩浆是1.0,通往下界的传送门是0.75.采集中的红石是0.625.
		super.setHarvestLevel(null, -1); // 开采砖块时需要使用的工具,可以是"pickaxe"(镐),
											// "shovel"(铲子)或"axe"(斧头).后面的数值为工具材质要求,-1(默认值)为可以直接手撕,0是木质和金质,1是石质,2是铁质,3是钻石质.
		super.setSoundType(SoundType.STONE);
		super.setCreativeTab(CreativeTabs.REDSTONE); // 设置创造模式表物品栏
		
	}
	
	public static CodeBlockScriptEngineManager getCodeBlockScriptEngineManager() {
		if (scriptEngineManager == null)
			scriptEngineManager = new CodeBlockScriptEngineManager();
		if (scriptEngineManager == null)
			throw new RuntimeException("BUG > CodeBlockScriptEngineManager is null!");
		return scriptEngineManager;
	}

	@Override
	public TileEntity createNewTileEntity(World worldIn, int meta) {
		TileEntityCodeBlock tileEntityCodeBlock = new TileEntityCodeBlock();
		return tileEntityCodeBlock;
	}

	@Override
	public EnumBlockRenderType getRenderType(IBlockState state) {
		return EnumBlockRenderType.MODEL;
	}

	@Override
	public boolean onBlockActivated(World worldIn, BlockPos pos, IBlockState state, EntityPlayer playerIn,
			EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ) {
		
		if (!worldIn.isRemote) {
			TileEntityCodeBlock tileentity = (TileEntityCodeBlock) worldIn.getTileEntity(pos);
			if (!playerIn.isSneaking()) {
				String msg = null;
				ItemStack nowHandItem = playerIn.getHeldItem(hand);
				if (nowHandItem.getUnlocalizedName().equals("tile.air")) {
					/*
					 * msg = LanguageTool.getDispalyName(
					 * "codeblockmod.block.codeBlock.mustBeCodeblockKey.notnull",
					 * BlockLoader.codeBlock, ItemLoader.itemCodeBlockKey);
					 */
				} else if (!ItemLoader.itemCodeBlockKey.getUnlocalizedName().equals(nowHandItem.getUnlocalizedName())) {
					msg = LanguageTool.getDispalyName("codeblockmod.block.codeBlock.mustBeCodeblockKey",
							BlockLoader.codeBlock, ItemLoader.itemCodeBlockKey, nowHandItem);
				} else {
					String group = tileentity.getGroup(),
						   nowKeyGroup = nowHandItem.getDisplayName(),
						   nowKeyDefalutName = LanguageTool.getDispalyName(nowHandItem);
					if (group != null && nowKeyGroup != null && nowKeyDefalutName != null) {
						boolean o = false;
						if (group.equals("NONE")) {
							if (!nowKeyGroup.equals(nowKeyDefalutName)) {
								tileentity.setGroup(nowKeyGroup);
							}
							o = true;
						} else if (group.equals(nowKeyGroup)) {
							o = true;
						}
						if (o) {
							GuiContainerCodeBlock.onIdeGuiOpen(tileentity, playerIn);
							playerIn.openGui(CodeBlockMod.instance, GuiElementLoader.GUI_Block_CodeBlock, worldIn, pos.getX(),
									pos.getY(), pos.getZ());
							// playerIn.closeScreen();
						} else {
							System.out.println("\n" + group + " - " + nowKeyGroup + " - " + nowKeyDefalutName);
							msg = LanguageTool.getDispalyName("codeblockmod.block.codeBlock.keyerror");
						}
						
					}
					
				}
				if (msg != null)
					playerIn.sendMessage(new TextComponentString(msg));
				return true;
			}
		}
		return false;
	}

	/**
	 * 当相邻块被更改时调用
	 */
	@Override
	public void neighborChanged(IBlockState state, World worldIn, BlockPos pos, Block blockIn, BlockPos fromPos) {
		if (!worldIn.isRemote) {
			TileEntityCodeBlock tileentity = (TileEntityCodeBlock) worldIn.getTileEntity(pos);
			if (tileentity != null) {
				boolean flag = worldIn.isBlockPowered(pos);
				// boolean flag1 = tileentity.isPowered();
				tileentity.setPowered(flag);
				if (flag) {
					if (tileentity.getLastRunTime() == -1) {
						tileentity.setLastRunTime(System.currentTimeMillis());
						String code = tileentity.getCode(),
								group = tileentity.getGroup();
						if (code != null && group != null && !code.equals("")) {
							ScriptEngine scriptEngine = getCodeBlockScriptEngineManager().getScriptEngine(group);
							// var
							String codeVar = tileentity.getVar();
							// System.out.println("\n保存的原数据：" + codeVar);
							if (codeVar == null || "".equals(codeVar)) {
								codeVar = "{}";
							} else {
								codeVar = new String(Base64.decodeBase64(codeVar.getBytes()));
							}
							// System.out.println("\n解析后的数据：" + codeVar);
							scriptEngine.put("CodeVar", codeVar);
							try {
								scriptEngine.eval(CodeBlockScriptEngineManager.CODEMOD_SCRIPT_GROUP_INIT);
							} catch (Exception e) {
								TextComponentString errMsg = new TextComponentString(String.format("[CODE>InitCodeVar>%d-%d-%d]: %s\n%s", pos.getX(), pos.getY(), pos.getZ(), e.toString(), codeVar));
								e.printStackTrace();
								try {
									Minecraft.getMinecraft().player.sendMessage(errMsg);
								} catch (Exception e2) {}
							}
							// Code
							Code codeObject = new Code(state, worldIn, pos, blockIn, fromPos);
							scriptEngine.put("Code", codeObject);
							try {
								scriptEngine.eval(CodeStringTool.analysis(code));
							} catch (Exception e) {
								TextComponentString errMsg = new TextComponentString(String.format("[CODE>%d-%d-%d]: %s", pos.getX(), pos.getY(), pos.getZ(), e.toString()));
								e.printStackTrace();
								try {
									Minecraft.getMinecraft().player.sendMessage(errMsg);
								} catch (Exception e2) {}
							}
							// clear CodeVer
							try {
								scriptEngine.eval(CodeBlockScriptEngineManager.CODEMOD_SCRIPT_CLEAR);
							} catch (Exception e) {
								TextComponentString errMsg = new TextComponentString(String.format("[CODE>ClearCodeVar>%d-%d-%d]: %s", pos.getX(), pos.getY(), pos.getZ(), e.toString()));
								e.printStackTrace();
								try {
									Minecraft.getMinecraft().player.sendMessage(errMsg);
								} catch (Exception e2) {}
							}
							String var = (String) scriptEngine.get("__BackCodeVar");
							// System.out.println("\n将保存的数据：" + var);
							if (var != null && !"".equals(var) && "{}".equals(var)) {
								var = new String(Base64.encodeBase64(var.getBytes()));
							}
							// System.out.println("\n编译后的保存数据：" + var);
							tileentity.setVar(var == null ? "" : var);
						}
						// System.out.println("\n可执行代码");
					}
				} else {
					tileentity.setLastRunTime(-1);
				}
			}
		}
	}

	@Override
	public int tickRate(World worldIn) {
		return 1;
	}

}
